mirror of https://github.com/wg-easy/wg-easy
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
2.7 KiB
109 lines
2.7 KiB
import * as client from 'openid-client';
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const { config, provider, providerConfig } = await buildOauthConfig(event);
|
|
|
|
const session = await useWGSession(event);
|
|
if (
|
|
!session.data.oauth_nonce ||
|
|
!session.data.oauth_verifier ||
|
|
!session.data.oauth_state
|
|
) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: 'Missing OAuth State',
|
|
});
|
|
}
|
|
|
|
const currentUrl = getRequestURL(event);
|
|
|
|
const tokens = await client.authorizationCodeGrant(config, currentUrl, {
|
|
pkceCodeVerifier: session.data.oauth_verifier,
|
|
expectedNonce:
|
|
providerConfig.isOIDC === false ? undefined : session.data.oauth_nonce,
|
|
expectedState: session.data.oauth_state,
|
|
idTokenExpected: providerConfig.isOIDC ?? true,
|
|
});
|
|
|
|
type SubjectType = string | undefined | typeof client.skipSubjectCheck;
|
|
let subject: SubjectType = tokens.claims()?.sub;
|
|
if (providerConfig.isOIDC === false) {
|
|
subject = client.skipSubjectCheck;
|
|
}
|
|
|
|
if (!subject) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: "Can't get subject",
|
|
});
|
|
}
|
|
|
|
let userInfo;
|
|
if (providerConfig.userInfoFlow === 'github') {
|
|
userInfo = await githubUserInfoFlow(tokens.access_token);
|
|
} else {
|
|
userInfo = await client.fetchUserInfo(config, tokens.access_token, subject);
|
|
}
|
|
|
|
if (!userInfo.sub) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: 'No sub set',
|
|
});
|
|
}
|
|
|
|
if (!userInfo.email) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: 'No email set',
|
|
});
|
|
}
|
|
|
|
if (!userInfo.email_verified) {
|
|
throw createError({
|
|
statusCode: 401,
|
|
statusMessage: 'Email is not verified',
|
|
});
|
|
}
|
|
|
|
const result = await Database.users.findOrCreateByProvider(
|
|
provider,
|
|
userInfo.sub,
|
|
userInfo.preferred_username || userInfo.email,
|
|
userInfo.email,
|
|
userInfo.name || 'User'
|
|
);
|
|
|
|
if (!result.success) {
|
|
if (result.error === 'USER_DISABLED') {
|
|
throw createError({
|
|
statusCode: 401,
|
|
statusMessage: 'User disabled',
|
|
});
|
|
}
|
|
if (result.error === 'USER_ALREADY_LINKED') {
|
|
throw createError({
|
|
statusCode: 401,
|
|
statusMessage: 'User already linked with different account or provider',
|
|
});
|
|
}
|
|
throw createError({
|
|
statusCode: 500,
|
|
statusMessage: 'Unexpected error',
|
|
});
|
|
}
|
|
|
|
// Create session
|
|
const data = await session.update({
|
|
userId: result.user.id,
|
|
oauth_nonce: undefined,
|
|
oauth_state: undefined,
|
|
oauth_verifier: undefined,
|
|
});
|
|
|
|
SERVER_DEBUG(
|
|
`New OAuth Session: ${data.id} for ${result.user.id} (${result.user.username}) with ${provider}`
|
|
);
|
|
|
|
return sendRedirect(event, '/');
|
|
});
|
|
|